package org.tsinghua.blockchain.client;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.tsinghua.blockchain.BlockChainException;
import org.tsinghua.blockchain.PropertiesConfigurator;
import org.tsinghua.blockchain.entity.FieldInfo;
import org.tsinghua.blockchain.entity.Message;
import org.tsinghua.blockchain.entity.RecordTypeInfo;
import org.tsinghua.blockchain.utils.TimeUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author ipenta
 * @ClassName: BlockChainProvider
 * @Description: 区块链供应类，基于RPC接口封装
 * @date 2017年4月6日 下午12:21:28
 */
@Component
public class BlockChainProvider {

	private static final Logger logger = LoggerFactory.getLogger(BlockChainProvider.class);

	@Autowired
	private BlockChainClient blockChainClient;

	@Autowired
	private PropertiesConfigurator propertiesConfigurator;


	// 创建记录，参数:map
	public Boolean createTxType(String name, List<FieldInfo> fieldInfos)
			throws BlockChainException {


		RecordTypeInfo recordTypeInfo = new RecordTypeInfo(name, fieldInfos);


		return messageConverter(blockChainClient.addTxType(recordTypeInfo, propertiesConfigurator.getPublicKey()));
	}


	// 创建记录，参数:map
	public Map<String, Object> createTx(String txType, Map<String, String> map, String referTxHash, List<String> authorizedUpdaters)
			throws BlockChainException {

		Map<String, Object> reqMap = new HashMap<>();

		String publicKey = propertiesConfigurator.getPublicKey();
		String privateKey = propertiesConfigurator.getPrivateKey();
		long timestamp = TimeUtils.getTxTimestamp();

		String archiveHash = null;

		String sign = messageConverter(
				blockChainClient.sign2(txType, map, timestamp, referTxHash, authorizedUpdaters, privateKey));

		if (null != sign) {
			archiveHash = messageConverter(
					blockChainClient.archive2(txType, map, timestamp, publicKey, sign, referTxHash, authorizedUpdaters));
			if (null != archiveHash) {
				reqMap.put("archiveHash", archiveHash);
				reqMap.put("createTime", timestamp);
			}
		}
		return reqMap;
	}


	/********* 辅助函数  ********/

	// 数据转换
	private <T> T messageConverter(Message<T> message) {
		if (message.getStatus().equals(Message.Status.SUCCESS.getValue())) {
			return message.getData();
		} else {
			logger.error("区块链接口出现错误：{},{}", message.getErrorCode(), message.getErrorContent());
			throw new BlockChainException("区块链接口出现错误：" + message.getErrorContent());
		}
	}


}
